//
//  CommentController.swift
//  App
//
//  Created by 汤泽川 on 2019/4/24.
//

import Foundation
import Vapor
import FluentMySQL

class CommentController : RouteCollection {
    func boot(router: Router) throws {
        router.post(RequestModel<QueryCommentRequest>.self, at: "query", use: queryCommentInfo)
        
        let userAuthRouter = router.grouped(UserAuthMiddleware())
        userAuthRouter.post(RequestModel<SendCommentRequest>.self, at: "send", use: sendComment)
    }
    
    func sendComment(_ req : Request, _ content : RequestModel<SendCommentRequest>) throws -> Future<Response> {
        if content.data.replayId == nil && content.data.storyId == nil {
            throw APIError.illegalCommentTarget
        }
        if content.data.content == "" {
            throw APIError.emptyCommentContent
        }
        return try UserAccessToken.queryUserInfo(accessToken: content.accessToken!, req: req).flatMap {
            userInfo in
            return CommentModel(id: nil, createdAt: nil, updatedAt: nil, replayId: content.data.replayId, storyId: content.data.storyId, userId: userInfo.id!, content: content.data.content).save(on: req).flatMap {
                commentModel in
                return try ResponseModel<CommentResponseInfo>.successResponse(CommentResponseInfo(commentInfo: commentModel, userInfo: userInfo, replayCount: 0)).encode(for: req)
            }
        }
    }
    
    func queryCommentInfo(_ req : Request, _ content : RequestModel<QueryCommentRequest>) throws -> Future<Response> {
        if content.data.replayId == nil && content.data.storyId == nil {
            throw APIError.illegalCommentTarget
        }
        var query = CommentModel.query(on: req)
        if content.data.storyId != nil {
            query = query.filter(\.storyId == content.data.storyId!)
        } else {
            query = query.filter(\.replayId == content.data.replayId!)
        }
        return query.join(\UserInfo.id, to: \CommentModel.userId).range(lower: content.data.page * content.data.count, upper:(content.data.page + 1 ) * content.data.count - 1).alsoDecode(UserInfo.self).sort(\CommentModel.createdAt, .descending).all().flatMap {
            result in
            return result.map {
                item in
                return CommentModel.query(on: req).filter(\CommentModel.replayId == item.0.id!).count()
                }.flatMap(to: Response.self, on: req) { commentCounts in
                    var datas = [CommentResponseInfo]()
                    for (index, item) in result.enumerated() {
                        datas.append(CommentResponseInfo(commentInfo: item.0, userInfo: item.1, replayCount: commentCounts[index]))
                    }
                    return try ResponseModel<[CommentResponseInfo]>.successResponse(datas).encode(for: req)
                }
        }
    }
}
